import React, { useCallback, useEffect, useLayoutEffect, useState } from "react";
import lodash from "lodash";
import { createProvider, StoreContext, createCombineProvider } from "./Provider";
import { CONST_VIEWSTOREREDUCERFLAG, CONST_VIEWSTORECOMBINEREDUCERFLAGB } from "../data";
import { useStore } from "./useStore";



export const createReducer = <IState extends {}, IAppState extends {}>({
    initState, name , handler}: AppViewStore.ICreateReducerOptions<IState, IAppState>): AppViewStore.ICreateReducer<IState> => {
    const StateProvider = createProvider<IState>(initState, handler, name);
    const createUseState = (stateKey: string) => {
        return () => {
            const store = useStore();
            const [ stateData, setStateData ] = useState(() => store.get(stateKey));
            const updateState = useCallback((newState: IState, action: any) => {
                store.set(stateKey, newState, action);
            }, []);
            useEffect(() => {
                return store.on(stateKey, (newState: IState) => {
                    if(!lodash.isEqual(stateData, newState)) {
                        setStateData(newState);
                    }
                });
            }, [stateData]);
            return {
                state: stateData as IState  || {},
                setState: updateState
            };
        };
    };
    const createResult = {
        flag: CONST_VIEWSTOREREDUCERFLAG,
        StateProvider,
        state: initState,
        name,
        handler,
        useViewState: createUseState(name) as any
    };
    (createResult as any).setName = (_name: string) => {
        createResult.name = _name;
        createResult.useViewState = createUseState(_name);
    }
    return createResult;
};

export const createCombineReducer = <ICombineReducerData={}>(
    parentReducer: AppViewStore.ICreateReducer<any>,
    combineReducers: Record<string, AppViewStore.ICreateReducer<any>>) => {
    const { Provider, useViewState } = createCombineProvider(parentReducer, combineReducers)
    return {
        flag: CONST_VIEWSTORECOMBINEREDUCERFLAGB,
        state: {},
        StateProvider: Provider,
        useViewState
    }
};